﻿/************************************************************************************
 * xujiajun@yoozoo.com 御剑
 * 使用相机高度作为依据的LOD策略
 ***********************************************************************************/
using WorldMapBase.Camera;
using WorldMapBase.LOD;
using System.Collections.Generic;
using BitBenderGames;
using UnityEngine;
using WorldMap.TouchCamera;
using WorldMapBase.Tile.Pool;

namespace WorldMapBase
{
    /// <summary>
    /// 根据摄像机的高度切分LOD等级的策略。默认最低高度为0。
    /// LOD等级起始值为0，换句话说最低LOD等级为0。每加一级LOD，数值加1，即第二级的LOD等级为1
    /// 下一级LOD的百分比数值为0-99的整型
    /// </summary>
    public class CameraHeightLODStrategy : LODStrategy
    {
        /// <summary>
        /// 默认的起始摄像机高度，值为0
        /// </summary>
        public static float Default_Start_Height = 0;

        /// <summary>
        /// 摄像机接口
        /// </summary>
        private ICamera m_Camera;

        /// <summary>
        /// 所有高度列表。起始值必为Default_Start_Distance的数值
        /// </summary>
        private List<float> m_CameraHeightList;

        /// <summary>
        /// 所有高度数量
        /// </summary>
        private int m_CameraHeightCnt;

        /// <summary>
        /// 上一帧LOD等级
        /// </summary>
        private int m_LastLODLevel;

        /// <summary>
        /// 上一帧LOD百分比
        /// </summary>
        private float m_LastLODPercent;

        /// <summary>
        /// 构造基于摄像机高度的LOD策略
        /// </summary>
        /// <param name="camera">相机对象</param>
        public CameraHeightLODStrategy(ICamera camera)
        {
            m_Camera = camera;
            Reset();
        }

        /// <summary>
        /// 添加每一级LOD的摄像机高度。添加一次高度即为增加一级LOD。请保持后一次添加的距离大于前一次
        /// </summary>
        /// <param name="height"></param>
        public void AddCameraHeight(float height)
        {
            if (m_CameraHeightList[m_CameraHeightCnt] > height)
            {
                Debug.LogError("添加的高度距离小于了前值");
            }
            m_CameraHeightList.Add(height);
            m_CameraHeightCnt++;
        }


        /// <summary>
        /// 添加每一级LOD的摄像机高度。添加一次高度即为增加一级LOD。请保持后一次添加的距离大于前一次
        /// </summary>
        /// <param name="height"></param>
        public void AddCameraHeightByLod(float lod)
        {
            float height = 0;
            switch (lod)
            {
                case 0f:
                    height = WorldEntry.DISTANCE_LOD0;
                    break;
                case 1f:
                    height = WorldEntry.DISTANCE_LOD1;
                    break;
                case 2f:
                    height = WorldEntry.DISTANCE_LOD2;
                    break;
                case 3f:
                    height = WorldEntry.DISTANCE_LOD3;
                    break;
                case 4f:
                    height = WorldEntry.DISTANCE_LOD4;
                    break;
                case 5f:
                    height = WorldEntry.DISTANCE_LOD5;
                    break;
                default:
                    break;
            }
            AddCameraHeight(height);
        }

        public override int GetLODLevel()
        {
            return m_LastLODLevel;
        }

        public override float GetNextLODPercent()
        {
            return m_LastLODPercent;
        }

        protected override void OnCreate()
        {

        }

        protected override void OnDestroy()
        {
            Reset();
        }

        private TouchCameraController _touchCameraController;
        
        protected override void OnUpdate()
        {
            if (_touchCameraController == null)
            {
                _touchCameraController = m_Camera.GetCamera().GetComponent<TouchCameraController>();
            }
            
            float currentheight = m_Camera.GetCameraHeight() + 0.001f;
            float currentFOV = m_Camera.GetCameraFOV();
            
            bool result = true;
			int lastLODLevel = m_LastLODLevel;

            if (_touchCameraController.ZoomMode == PerspectiveZoomMode.FIELD_OF_VIEW)
            {
                m_LastLODLevel = 0;
                m_LastLODPercent = (currentFOV - _touchCameraController.CameraGlobalValue.MIN_FOV) * 100.0f/
                                   (_touchCameraController.CameraGlobalValue.MAX_FOV - _touchCameraController.CameraGlobalValue.MIN_FOV);
                m_LastLODPercent = Mathf.Max(0, Mathf.Min(m_LastLODPercent, 100));
                result = false;
            }
            else
            {
                for (int i = 0; i < m_CameraHeightCnt; i++)
                {
                    var prevHeight = m_CameraHeightList[i];
                    var nextHeight = m_CameraHeightList[i + 1];
                    if (prevHeight <= currentheight && currentheight < nextHeight)
                    {
                        if (i != 0)
                        {
                            // 找到了符合区间范围的LOD等级
                            m_LastLODLevel = i;
                            m_LastLODPercent = ((currentheight - prevHeight) * 100.0f / (nextHeight - prevHeight));
                            result = false;
                            break;
                        }
                        else
                        {
                            m_LastLODLevel = 0;
                            m_LastLODPercent = (currentFOV - _touchCameraController.CameraGlobalValue.MIN_FOV) * 100.0f/
                                               (_touchCameraController.CameraGlobalValue.MAX_FOV - _touchCameraController.CameraGlobalValue.MIN_FOV);
                            m_LastLODPercent = Mathf.Max(0, Mathf.Min(m_LastLODPercent, 100));
                            result = false;
                        }
                    }
                }
            }

            if (result)
            {
                // 如果没有找到区间。dis小于起始高度则是最小等级，否则为最大等级
                if (currentheight < Default_Start_Height)
                {
                    m_LastLODLevel = 0;
                    m_LastLODPercent = 0;
                }
                else
                {
                    m_LastLODLevel = m_CameraHeightCnt - 1;
                    m_LastLODPercent = 100;
                }
            }
            // Debug.LogError("[层级问题调试2] 当前层级：" + m_LastLODLevel +
            //                "  lod0:" + m_CameraHeightList[0] +
            //                " lod1: " + m_CameraHeightList[1] + 
            //                "  Camera Height: " + currentheight);
            
        }
        
        /// <summary>
        /// 获取LOD等级
        /// </summary>
        /// <returns></returns>
        public int GetLastLODLevel()
        {
            return GetLODLevel();
        }
        
        /// <summary>
        /// 获取LOD百分比
        /// </summary>
        /// <returns></returns>
        public float GetLastLODPercent()
        {
            return GetNextLODPercent();
        }

        

        /// <summary>
        /// 重置策略数据
        /// </summary>
        private void Reset()
        {
            m_CameraHeightList = new List<float>();
            m_LastLODLevel = 0;
            m_LastLODPercent = 0;
            m_CameraHeightCnt = 0;
            m_CameraHeightList.Add(Default_Start_Height);
        }
    }
}

